package ntd.util.frame.task.handle.fm.util;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.c.opt.query.ComOptQueryWrapper;
import com.ToolOpt;
import ntd.util.frame.task.handle.fm.bo.DataItemTempBO;
import ntd.util.frame.task.handle.fm.bo.DataTempBO;
import ntd.util.modular.data.entity.DataAcquisitionRecords;
import com.c.Constant;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public class UtilDevice {

    private static List<DataAcquisitionRecords> listDevice(String ruleId, Integer size) {

        ComOptQueryWrapper comOptQueryWrapper = ToolOpt.OPT_D_A_RECORDS.query().eq("data_acquisition_rule_id", ruleId);

        return ToolOpt.OPT_D_A_RECORDS.pageBean(comOptQueryWrapper, 1, ObjectUtil.defaultIfNull(size, 1));
    }

    private static Map<String, Function<DataAcquisitionRecords, List<DataTempBO>>> functionMap = new HashMap();

    static {
        functionMap.put("402809817f97b548017f9c30855900d8", dataAcquisitionRecords -> {
            List<DataTempBO> dataTempBOS = new ArrayList<>();

            String content = dataAcquisitionRecords.getContent();

            JSONArray list = JSONUtil.parseObj(content).getJSONObject("data").getJSONArray("list");

            for (int i = 0; i < list.size(); i++) {
                DataTempBO dataTempBO = new DataTempBO();
                JSONObject item = list.getJSONObject(i);
                dataTempBO.setDeviceNo(item.getStr("deviceNo"));
                LocalDateTime eventTime = LocalDateTimeUtil.parse(item.getStr("eventTime"),
                        Constant.DATE_FORMAT_WLW_THREE);
                dataTempBO.setReportDate(eventTime);
                dataTempBO.setStatus(item.getInt("status"));

                Integer angle = item.getInt("angle");
                if (angle > 150) {
                    angle = 180 - angle;
                }

                DataItemTempBO dataItemTempBO1 = new DataItemTempBO();
                dataItemTempBO1.setVal(angle.toString());
                dataItemTempBO1.setName("角度");
                dataItemTempBO1.setDataTag(Boolean.TRUE);
                dataItemTempBO1.setCode(FactoryFactor.getCodeByName("角度"));
                dataItemTempBO1.setDate(LocalDateTimeUtil.formatNormal(eventTime));

                DataItemTempBO dataItemTempBO2 = new DataItemTempBO();
                dataItemTempBO2.setVal("0");
                dataItemTempBO2.setName("气体浓度");
                dataItemTempBO2.setDataTag(Boolean.TRUE);
                dataItemTempBO2.setCode(FactoryFactor.getCodeByName("气体浓度"));
                dataItemTempBO2.setDate(LocalDateTimeUtil.formatNormal(eventTime));

                DataItemTempBO dataItemTempBO3 = new DataItemTempBO();
                dataItemTempBO3.setVal(item.getStr("temp"));
                dataItemTempBO3.setName("温度");
                dataItemTempBO3.setDataTag(Boolean.TRUE);
                dataItemTempBO3.setCode(FactoryFactor.getCodeByName("温度"));
                dataItemTempBO3.setDate(LocalDateTimeUtil.formatNormal(eventTime));

                DataItemTempBO dataItemTempBO4 = new DataItemTempBO();
                dataItemTempBO4.setVal(item.getStr("voltage"));
                dataItemTempBO4.setName("电压");
                dataItemTempBO4.setDataTag(Boolean.FALSE);
                dataItemTempBO4.setCode(FactoryFactor.getCodeByName("电压"));
                dataItemTempBO4.setDate(LocalDateTimeUtil.formatNormal(eventTime));

                DataItemTempBO dataItemTempBO5 = new DataItemTempBO();
                dataItemTempBO5.setVal(item.getStr("shakeSize"));
                dataItemTempBO5.setName("震动次数");
                dataItemTempBO5.setDataTag(Boolean.FALSE);
                dataItemTempBO5.setCode(FactoryFactor.getCodeByName("震动次数"));
                dataItemTempBO5.setDate(LocalDateTimeUtil.formatNormal(eventTime));

                List<DataItemTempBO> data = dataTempBO.getData();
                data.add(dataItemTempBO1);
                data.add(dataItemTempBO2);
                data.add(dataItemTempBO3);
                data.add(dataItemTempBO4);
                data.add(dataItemTempBO5);

                dataTempBOS.add(dataTempBO);
            }

            return dataTempBOS;
        });
        functionMap.put("402896817f969933017f96aa34c10007", dataAcquisitionRecords -> {
            final String[] typeNames = {"", "压力", "液位", "温度"};

            DataTempBO dataTempBO = new DataTempBO();
            String content = dataAcquisitionRecords.getContent();
            JSONObject item = JSONUtil.parseObj(content).getJSONObject("service").getJSONObject("data");

            dataTempBO.setDeviceNo(item.getStr("Imei"));
            dataTempBO.setReportDate(LocalDateTimeUtil.parse("20" + item.getStr("sendTime"),
                    Constant.DATE_FORMAT_WLW_TWO));

            String typeName = typeNames[item.getInt("deviceType")];
            List<DataItemTempBO> dataItemTempBOS = dataTempBO.getData();

            // 因子数据
            DataItemTempBO dataItemTempBO = new DataItemTempBO();
            dataItemTempBO.setDate(LocalDateTimeUtil.formatNormal(dataTempBO.getReportDate()));
            dataItemTempBO.setVal(UtilDataTpse.transform(item.getStr("sampleData")));
            dataItemTempBO.setUnit(item.getStr("unit"));
            dataItemTempBO.setCode(FactoryFactor.getCodeByName(typeName));
            dataItemTempBO.setName(typeName);
            dataItemTempBO.setDataTag(Boolean.TRUE);
            dataItemTempBOS.add(dataItemTempBO);

            DataItemTempBO dataItemTempBOTwo = new DataItemTempBO();
            dataItemTempBOTwo.setDate(LocalDateTimeUtil.formatNormal(dataTempBO.getReportDate()));
            dataItemTempBOTwo.setVal(item.getStr("batteryLevel"));
            dataItemTempBOTwo.setUnit(item.getStr("%"));
            dataItemTempBOTwo.setCode("batteryLevel");
            dataItemTempBOTwo.setName("电量");
            dataItemTempBOS.add(dataItemTempBOTwo);

            DataItemTempBO dataItemTempBOThree = new DataItemTempBO();
            dataItemTempBOThree.setDate(LocalDateTimeUtil.formatNormal(dataTempBO.getReportDate()));
            dataItemTempBOThree.setVal(item.getStr("signalStrength"));
            dataItemTempBOThree.setUnit(item.getStr("%"));
            dataItemTempBOThree.setCode("signalStrength");
            dataItemTempBOThree.setName("信号强度");
            dataItemTempBOS.add(dataItemTempBOThree);

            return ListUtil.of(dataTempBO);
        });
        functionMap.put("402896817f8b509e017f8b59acc90008", dataAcquisitionRecords -> {
            DataTempBO dataTempBO = new DataTempBO();
            String content = dataAcquisitionRecords.getContent();
            JSONObject jsonObj = JSONUtil.parseObj(content).getJSONObject("data");
            if (ObjectUtil.isNull(jsonObj)) {
                return ListUtil.of();
            }
            dataTempBO.setDeviceNo(jsonObj.getStr("deviceNo"));
            dataTempBO.setDeviceIP(jsonObj.getStr("deviceIP"));
            dataTempBO.setDeviceName(jsonObj.getStr("deviceName"));
            dataTempBO.setReportDate(LocalDateTimeUtil.parse(jsonObj.getStr("connDate"), Constant.DATE_FORMAT_STAND));

            List<DataItemTempBO> dataItemTempBOS = dataTempBO.getData();

            JSONArray sensors = jsonObj.getJSONArray("sensors");
            for (int i = 0; i < sensors.size(); i++) {
                DataItemTempBO dataItemTempBO = new DataItemTempBO();
                JSONObject item = sensors.getJSONObject(i);

                dataItemTempBO.setDate(item.getStr("time"));
                dataItemTempBO.setVal(item.getStr("value"));
                dataItemTempBO.setUnit(item.getStr("unit"));
                dataItemTempBO.setCode(FactoryFactor.getCodeByName(item.getStr("name")));
                dataItemTempBO.setName(item.getStr("name"));
                dataItemTempBO.setDataTag(Boolean.TRUE);

                dataItemTempBOS.add(dataItemTempBO);
            }
            return ListUtil.of(dataTempBO);
        });
        functionMap.put("40288a9e7f62e50c017f62e9f8130003", dataAcquisitionRecords -> {
            String content = dataAcquisitionRecords.getContent();
            DataTempBO dataTempBO = new DataTempBO();
            dataTempBO.setDeviceNo(StrUtil.sub(dataAcquisitionRecords.getRequestUrl(), 42, 51));
            List<DataItemTempBO> dataItemTempBOS = dataTempBO.getData();
            JSONArray monitorings = JSONUtil.parseObj(content).getJSONArray("monitorings");
            if (CollectionUtil.isEmpty(monitorings)) {
                return ListUtil.of(dataTempBO);
            }
            for (int i = 0; i < monitorings.size(); i++) {
                DataItemTempBO dataItemTempBO = new DataItemTempBO();
                JSONObject item = monitorings.getJSONObject(i);
                dataItemTempBO.setDate(item.getStr("dataTime"));
                dataItemTempBO.setCode(FactoryFactor.getCodeByName(item.getStr("monitoringName")));
                dataItemTempBO.setName(item.getStr("monitoringName"));
                dataItemTempBO.setUnit(item.getStr("unit"));
                dataItemTempBO.setVal(item.getStr("dataValue"));
                if ("液位".equals(dataItemTempBO.getName())) {
                    dataItemTempBO.setDataTag(Boolean.TRUE);
                }
                dataItemTempBOS.add(dataItemTempBO);
            }
            return ListUtil.of(dataTempBO);
        });
    }

    public static Map<String, List<DataTempBO>> getDeviceMap() {
        List<String> ruleIds = ListUtil.of("402809817f97b548017f9c30855900d8", "402896817f969933017f96aa34c10007",
                "402896817f8b509e017f8b59acc90008", "40288a9e7f62e50c017f62e9f8130003");
        List<DataTempBO> dataTempBOList = new ArrayList<>();
        for (String ruleId : ruleIds) {
            for (DataAcquisitionRecords dataAcquisitionRecord : listDevice(ruleId, 5)) {
                String content = dataAcquisitionRecord.getContent();
                if (StrUtil.isNotBlank(content)) {
                    dataTempBOList.addAll(functionMap.get(ruleId).apply(dataAcquisitionRecord));
                }
            }
        }

        return CollStreamUtil.groupByKey(dataTempBOList, DataTempBO::getDeviceNo);
    }
}
